<?php

/**
 * WordPress PDK Form
 *
 * This aims to make the painful task creating admin form easy
 * Everytime a new instance of this class is created, you must specify
 * a scenario. This will then be used as the auth salt for the wp_create_nonce
 */

require_once('wp_pdk_validators.php');

class WordPress_PDK_Form
{
	/**
	 * @var string - new line
	 */
	const NL = "\n";
	
	
	/**
	 * @var string - the scenario
	 */
	public $scenario = '';
	
	
	/**
	 * @var array - submitted form attributes
	 */
	public $attributes = array();
	
	
	/**
	 * @var string - error label class
	 */
	public $errorLabelClass = 'error';
	
	
	/**
	 * @var string - field label class
	 */
	public $fieldErrorClass = 'error';
	
	
	/**
	 * @var array - attriute validators
	 */
	public $validators = array();
	
	
	/**
	 * @var array - atribute errors
	 */
	private $_attributeErrors = array();
	
	
	 
	/**
	 * The constructor
	 *
	 * @param string - the form scenario
	 */
	public function __construct( $scenario = '' )
	{
		if(empty($scenario)) {
			return false;
		}
		
		$this->scenario = $scenario;
	}
	
	
	/**
	 * Get magic function
	 */
	public function __get( $name )
	{
		if(isset($this->attributes[$name])) {
			return addslashes($this->attributes[$name]);
		}
	}
	
	
	/**
	 * Create a form opening tag
	 *
	 * @param string - the action for the form
	 * @param string - the form method (post/get)
	 * @param array - specifiy any other form paramaters
	 * @return string
	 */
	public function beginForm( $action = '', $method = 'post', $htmlOptions = array() )
	{
		$str = '<form method="' . $method . '" action="' . $action . '"';
		$str .= $this->_optionsString($htmlOptions) . '>';
		
		return $str;
	}
	
	
	/**
	 * Close the form
	 *
	 * @return string
	 */
	public function endForm()
	{
		$str = '<input type="hidden" name="' . $this->scenario . '[token]" value="' . wp_create_nonce($this->scenario) . '" />';
		$str .= "</form>\n";
		return $str;
	}
	
	
	/**
	 * Submit button
	 *
	 * @param string - the button label
	 * @param array - html options
	 * @return string - the button html
	 */
	public function submitButton( $value = 'Submit', $htmlOptions = array() )
	{
		$str = '<input type="submit" value="' . $value . '"' . $this->_optionsString($htmlOptions) . ' />';
		return $str;
	}
	
	
	/**
	 * label
	 *
	 * @param string - the label value
	 * @param string - the label name
	 * @param array - html options
	 * @return string - the label
	 */
	public function label( $value = '', $name, $htmlOptions = array() )
	{
		if(isset($this->_attributeErrors[$name])) {
			$class = isset($htmlOptions['class']) ? $htmlOptions['class'] . ' ' . $this->errorLabelClass : $this->errorLabelClass;
			$htmlOptions['class'] = $class;
		}
			
		$str = '<label for="' . $this->scenario . '[' . $name . ']"' . $this->_optionsString($htmlOptions) . '>' . $value . '</label>'.self::NL;
		return $str;
	}
	
	
	/**
	 * TextField
	 *
	 * @param string - the attribute name
	 * @param array - html options
	 * @return string - the input text field
	 */
	public function textField( $name, $htmlOptions = array() )
	{
		if(isset($this->_attributeErrors[$name])) {
			$class = isset($htmlOptions['class']) ? $htmlOptions['class'] . ' ' . $this->errorLabelClass : $this->errorLabelClass;
			$htmlOptions['class'] = $class;
		}
		
		$str = '<input type="text" name="' . $this->scenario . '[' . $name . ']" id="' . $this->_createIdFromName($name) . '"' . $this->_optionsString($htmlOptions) . ' />'.self::NL;
		return $str;
	}
	
	
	
	/**
	 * Output an attribute error
	 *
	 * @param string - the attribute
	 * @return mixed
	 */
	public function error( $attribute )
	{
		if(isset($this->_attributeErrors[$attribute])) {
			$str = $this->_attributeErrors[$attribute][0];
			return $str;
		}
	}
	
	
	/**
	 * Create a valid id from name
	 *
	 * @param string - the input name
	 * @return string - the newly formd ID string
	 */
	private function _createIdFromName( $name )
	{
		return $this->scenario . '_' . $name;
	}
	
	
	/**
	 * Options string
	 *
	 * @array - the string of html options
	 * @return string
	 */
	private function _optionsString( $options = array() )
	{
		$str = '';
		
		if(count($options) > 0) {
			foreach($options as $key => $val) {
				$str .= ' ' . $key . '="' . $val . '"';
			}
		}
		
		return $str;
	}
	
	
	/**
	 * add an error
	 *
	 * @param string - the form element
	 * @param string - the message
	 */
	private function _addError( $attribute, $message )
	{
		if(isset($this->_attributeErrors[$attribute])) {
			array_push($this->_attributeErrors[$attribute], $message);
		} else {
			$this->_attributeErrors[$attribute] = array($message);
		}
	}
	
	
	/**
	 * Validate the form
	 */
	public function validate()
	{
		foreach($this->validators as $array) {
			$attribute = $array[0];
			$validator = $array[1];
			$params = count($array) > 2 ? array_slice($array,2) : array();
			$check = new WordPress_PDK_Validators( $validator, $this->attributes[$attribute], $params );
			if(!$check->pass()) {
				$this->_addError($attribute, $check->errorMessage);
			}
		}
		return !count($this->_attributeErrors) > 0;
	}
}

?>